import jwt
import datetime
from flaskapp.util.Result import Result
from flaskapp.entity.User import User
from flask import request
from functools import wraps

SECRET_KEY = 'BOOKS_PUBLIC_KEY'


# 生成Token
def generate_token(userid, is_admin=False):
    try:
        payload = {
            'exp': datetime.datetime.utcnow() + datetime.timedelta(days=7),
            'iat': datetime.datetime.utcnow(),
            'userid': userid,
            'is_admin': is_admin
        }
        return jwt.encode(
            payload,
            SECRET_KEY,
            algorithm='HS256'
        )
    except Exception as e:
        return e


# 解析Token
def decode_token(token):
    """ 解码Token并处理异常 """
    try:
        payload = jwt.decode(token, SECRET_KEY, algorithms=['HS256'])
        exp = payload.get('exp')  # 获取过期时间
        if exp is None or datetime.datetime.utcfromtimestamp(exp) < datetime.datetime.utcnow():
            return False, 'token已过期'
        return payload['userid']  # 返回成功标志和用户ID
    except jwt.ExpiredSignatureError as e:
        return False
    except jwt.InvalidTokenError as e:
        return False


# 查询用户状态
def check_token(token):
    user_id = decode_token(token)
    print(user_id)
    token_in_user = User.query.filter_by(token=token).first()

    # 根据是否开启多端登陆判断token是否有效
    multi_device_login = True
    if not multi_device_login and not token_in_user:
        return False, 'token过期'

    if user_id:
        user = User.query.get(user_id)
        if user:
            return True, user
        else:
            return False, '用户不存在'
    else:
        return False, 'token无效'


# Token检查
# def user_token_required(f):
#     @wraps(f)
#     def decorated_function(*args, **kwargs):
#         token = request.headers.get('token')
#         if not token:
#             return Result.error(401,"token不存在")
#
#         user_info = check_token(token)
#         return f(*args, **kwargs, user_info=user_info)
#
#     return decorated_function
#


# Token检查
def user_token_required(admin_required=False):
    def decorator(f):
        @wraps(f)
        def decorated_function(*args, **kwargs):
            token = request.headers.get('token')
            if not token:
                return Result.error(401, "token不存在")

            is_valid, user_info = check_token(token)
            if not is_valid:
                return Result.error(401, user_info)

            if admin_required and not user_info.is_admin:
                return Result.error(403, "权限不足")

            return f(*args, **kwargs, user_info=user_info)

        return decorated_function

    return decorator
